/**
 * 
 */
package visualization.singleview;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.JPanel;
import javax.swing.JTextField;

import math.Quality;
import dataTypes.ISequenceData;

/**
 * @author Christian
 * 
 */
public class DynamicWindowPanel extends JPanel implements MouseMotionListener{
	private static final int NUMBEROFWINDOWSIZES = 2;
	private static final int SMALLESTWINDOW = 1;
	private static final int WINDOWSIZESTEP = 30;

	double[][] qualityAvg;
	double[] qualityDynamic;
	int maxQuality = 0;
	int seqLength;
	ISequenceData seqData;

	JTextField seqTF;

	public DynamicWindowPanel(ISequenceData seqData) {
		super();

		seqTF = new JTextField();
		seqTF.setSize(120, 15);
		this.add(seqTF);

		this.addMouseMotionListener(this);
		this.seqData = seqData;
		seqLength = seqData.getSeqLength();

		qualityDynamic = Quality.calcDynamicWindowQuality(seqData, 12);

		qualityAvg = Quality.calcWindowQuality(seqData, SMALLESTWINDOW,
				WINDOWSIZESTEP, NUMBEROFWINDOWSIZES);
		byte[] quality = seqData.getSeqQuality();
		for (int i = 0; i < seqLength; i++) {
			if (quality[i] > maxQuality) {
				maxQuality = quality[i];
			}
		}

	}

	public void paintComponent(Graphics g) {
		super.paintComponents(g);

		// Calculate window size, scale factor and offset.
		int width = this.getWidth();
		double scaleW = (double) (width * 0.8) / seqLength;
		int height = this.getHeight();
		double scaleH = (double) height / (maxQuality + 5);

		int offset = (int) (width * 0.1);

		// Draw scale on rigth side:
		g.setColor(Color.BLACK);
		for (int i = 0; i <= maxQuality + 5; i += 10) {
			g.drawLine(width - 10, (int) (height - (i * scaleH)), width,
					(int) (height - (i * scaleH)));
			g.drawString(String.valueOf(i), width - 30,
					(int) (height - (i * scaleH)) + 5);
			g.setColor(Color.gray);
			g.drawLine(offset, (int) (height - (i * scaleH)), width - 40,
					(int) (height - (i * scaleH)));
			g.setColor(Color.BLACK);
		}

		// Draw bottom scale
		if (scaleW > 1) {

			for (int i = 0; i < seqLength; i++) {
				int drawPos = (int) (i * scaleW) + offset;
				boolean drawNumber = false;
				if (i % 10 == 0) {
					if (scaleW < 3) {
						if (i % 50 == 0) {
							drawNumber = true;
						}
					} else {
						drawNumber = true;
					}
				}
				if (i == seqLength - 1 || i == 0) {
					drawNumber = true;
				}
				if (drawNumber) {
					g.drawString(String.valueOf(i), drawPos - 4, height - 17);
					g.drawLine(drawPos, height, drawPos, height - 15);
					g.setColor(Color.GRAY);
					g.drawLine(drawPos, height - 30, drawPos, 50);
					g.setColor(Color.BLACK);
				} else {
					g.drawLine(drawPos, height, drawPos, height - 10);
				}

			}
		}

		// Draw actual data:

		for (int x = 0; x < seqLength - 1; x++) {
			// Draw fixed size window curves:
			for (int window = 0; window < NUMBEROFWINDOWSIZES; window++) {
				g
						.setColor(new Color(0, (255 / NUMBEROFWINDOWSIZES)
								* window, 0));
				g.drawLine((int) ((x * scaleW) + offset),
						(int) (height - qualityAvg[window][x] * scaleH),
						(int) (((x + 1) * scaleW) + offset),
						(int) (height - qualityAvg[window][x + 1] * scaleH));
			}
			// Draw dynamic window size curve:
			g.setColor(Color.RED);
			g.drawLine((int) ((x * scaleW) + offset),
					(int) (height - qualityDynamic[x] * scaleH),
					(int) (((x + 1) * scaleW) + offset),
					(int) (height - qualityDynamic[x + 1] * scaleH));
		}

	}

	public void mouseDragged(MouseEvent e) {
		// Do nothing...
	}

	public void mouseMoved(MouseEvent e) {
		if (e.getPoint().x > (int) this.getWidth() * 0.1
				&& e.getPoint().x < (int) this.getWidth() * 0.9
				&& this.getWidth() > seqLength) {
			double scaleW = (double) (this.getWidth() * 0.8) / seqLength;
			int seqX = e.getPoint().x - (int) (this.getWidth() * 0.1);

			int centerBase = (int) Math.ceil((double) (seqX / scaleW));

			int seqStart = Math.max(0, centerBase - 6);
			int seqEnd = Math.min(seqLength - 1, centerBase + 4);

			String seqToDisplay = "";
			for (int i = seqStart; i < seqEnd; i++) {
				seqToDisplay += (char) seqData.getSeqData()[i];
			}
			if (seqTF.getText().compareTo(seqToDisplay) != 0) {
				seqTF.setText(seqToDisplay);
			}

		}
	}
}
